#include "CCoroutine.h"
#include <exception>
#include "CCoroutineImpl.h"
#include "CCoroutineTimerContext.h"

namespace TB
{
	thread_local std::shared_ptr<CCoroutine> CCoroutine::m_poCurrent;

	CCoroutine::CCoroutine(const std::weak_ptr<CThreadPool>& poThreadPool):
		CCoroutine({}, {}, poThreadPool, false)
	{
	}

	CCoroutine::CCoroutine(bool bManualPoll):
		CCoroutine({}, {}, {}, bManualPoll)
	{
	}

	CCoroutine::CCoroutine(CCoroutineGroup* poGroup, const std::weak_ptr<CCoroutineGroupImpl>& poGroupImpl, const std::weak_ptr<CThreadPool>& poThreadPool, bool bManualPoll):
		m_poGroup(poGroup)
	{
		m_poImpl = std::make_shared<CCoroutineImpl>(poGroupImpl, poThreadPool, &CCoroutine::_SetCurrent, bManualPoll);
		m_poImpl->m_poSelf = m_poImpl;
		m_poTimerMgr = &m_poImpl->m_poTimerContext->GetTimerMgr();
	}

	CCoroutine::~CCoroutine()
	{
	}

	void CCoroutine::Init(const std::weak_ptr<CCoroutine>& poSelf)
	{
		m_poImpl->Init(poSelf);
	}

	UINT64 CCoroutine::GetID() const
	{
		return m_poImpl->GetID();
	}

	void CCoroutine::_Post(const std::function<void()>* pcbFunction)
	{
		m_poImpl->Post(pcbFunction, false);
	}

	const std::weak_ptr<CThreadPool>& CCoroutine::GetThreadPool() const
	{
		return m_poImpl->m_poThreadPool;
	}

	std::weak_ptr<CThreadPool>& CCoroutine::GetThreadPool()
	{
		return m_poImpl->m_poThreadPool;
	}
}